﻿#include "study14.h"
// C/C++ 标准库学习网站：https://legacy.cplusplus.com
// C/C++ 参考学习网站：https://zh.cppreference.com/w/cpp
// C/C++ 微软(Visual Studio)中文学习网站：https://learn.microsoft.com/zh-cn/cpp/cpp/?view=msvc-170
// OpenGl 学习网站：https://docs.gl/

/*
异常处理机制是C++中非常重要的特性之一，它可以帮助我们在程序运行过程中更好地处理错误。
    关键字 try 用于指定异常处理代码块，关键字 catch 用于捕获异常，关键字 throw 用于抛出异常。
    throw 关键字可以抛出任意类型的异常，包括用户自定义的异常类型；在 try 代码块中捕获到 throw 语句抛出的异常，可以根据需要进行相应的处理；比如在 catch 语句中输出
这里以微软官网给出的代码为例，演示一下异常处理的基本用法。
*/

using namespace std;

class MyException {};
class Dummy {
public:
    string MyName;
    int level;
    Dummy(string s) : MyName(s) { PrintMsg("Created Dummy:"); }
    Dummy(const Dummy& other) : MyName(other.MyName) { PrintMsg("Copy created Dummy:"); }
    ~Dummy() { PrintMsg("Destroyed Dummy:"); }
    void PrintMsg(string s) { cout << s << MyName << endl; }
};

void C(Dummy d, int i) {
    cout << "Entering Function C" << endl;
    d.MyName = " C";
    throw MyException();

    cout << "Exiting Function C" << endl;
}

void B(Dummy d, int i) {
    cout << "Entering Function B" << endl;
    d.MyName = " B";
    C(d, i + 1);
    cout << "Exiting Function B" << endl;
}

void A(Dummy d, int i) {
    cout << "Entering Function A" << endl;
    d.MyName = " A";
    //  Dummy* pd = new Dummy("new Dummy"); //Not exception safe!!!
    B(d, i + 1);
    //   delete pd;
    cout << "Exiting Function A" << endl;
}

void test_exception() {
    cout << "Entering main" << endl;
    try {
        Dummy d(" M");
        A(d, 1);
    }
    catch (MyException& e) {
        cout << "Caught an exception of type: " << typeid(e).name() << endl;
    } // typeid 主要用于获取类型的运行时类型信息，在多态里面常用

    cout << "Exiting main." << endl;
    //char c;
    //cin >> c; // 等待用户输入，防止程序结束后自动关闭窗口
}

/* Output:
    Entering main
    Created Dummy: M
    Copy created Dummy: M
    Entering Function A
    Copy created Dummy: A
    Entering Function B
    Copy created Dummy: B
    Entering Function C
    Destroyed Dummy: C
    Destroyed Dummy: B
    Destroyed Dummy: A
    Destroyed Dummy: M
    Caught an exception of type: class MyException
    Exiting main.

*/